home *** CD-ROM | disk | FTP | other *** search
- /*
- ** TESTDRV
- **
- ** Device Driver Test for MSCDEX compatible CD-ROM
- **
- ** Note: several routines taken from audio.c and speed.c
- **
- ** FILE: support.c
- **
- ** HISTORY:
- ** 10/01/90 Final (v1.0) -by- JYG
- ** 12/06/91 Revision Siddhartha Roy
- */
-
- #include<ctype.h>
- #include<malloc.h>
-
- #include "test.h"
-
- static union REGS inregs;
- static union REGS outregs;
- static struct SREGS segregs;
-
- /*
- ** int VolLabel( WORD iDrive, char * szName )
- ** Returns the volume label of iDrive in szName
- */
-
- char * VolLabel( iDrive, szName )
- WORD iDrive;
- char * szName;
- {
- char * szPath = "C:\*.*";
- struct find_t Buf;
- extern WORD iFirstDrvLetter;
- #ifdef DEBUG
- printf ( "\n Drive # %u, FirstDrive # %u\n", iDrive, iFirstDrvLetter );
- #endif
- sprintf( szPath,"%c:\\*.*",(char) (iDrive + iFirstDrvLetter) + 'A' );
-
- #ifdef DEBUG
- printf ( "\n Using Path : %s \n",szPath );
- #endif
-
- _dos_findfirst( szPath,_A_VOLID,&Buf );
-
- strcpy ( szName,Buf.name );
-
- #ifdef DEBUG
- printf ( "\n Volume Label : %s\n", szName);
- #endif
-
- return ( szName );
-
- }
-
- /*
- ** Fatal Program errors
- */
-
- void fatalError( msg )
- char * msg;
- {
- fprintf( stdout,"\n%s: Fatal Error, %s \n",PROGNAME,msg );
- exit( 1 );
- }
-
- // It is the responsibilty of the device driver writer to set the
- // bits properly in the status word. Here we simply give the info
- // as to whether BUSY/DONE/ERROR are set or not.
-
- WORD InterpStatus( wStatus )
- WORD wStatus;
- {
- if ( ERRORBIT&wStatus ) printf( "ERROR 0x%0.2x:",wStatus&ERRORMASK );
- if ( BUSYBIT&wStatus ) printf( "BUSY:" );
- if ( DONEBIT&wStatus ) printf( "DONE:" );
- return wStatus;
- }
-
- /*
- ** Ask(char *)
- ** - prompts the user for a yes/no question expecting
- ** 'Y' (default on return) returns TRUE for yes, FALSE
- ** for no
- */
-
- char Ask ( chQuestion )
- char * chQuestion;
- {
- char chResponse;
- extern FLAG fInteract;
-
- do
- {
- printf( "\n\t\t%s? [Yncq] ",chQuestion );
- chResponse = (char)getche();
- if ( chResponse == ' ' || chResponse == '\n' )
- return TRUE;
- switch (tolower(chResponse))
- {
- case 'y':
- return TRUE;
- break;
- case 'c':
- fInteract = FALSE;
- return TRUE;
- break;
- case 'q':
- fprintf(stdout,"\n\tExiting...........");
- exit(1);
- break;
- case 'n':
- return FALSE;
- break;
- default:
- break;
- }
-
- }
- while ( TRUE );
- }
-
- /*
- ** Msg(BYTE,BYTE,const char *,char *)
- ** - Generic informative pretty print
- */
-
- void Msg(sLabel, szStat,szMsg)
- ReqName sLabel;
- char *szStat,*szMsg;
- {
- if (sLabel.bCmd != 0)
- printf("\n%d:%d\t%s\t%s\t %s",sLabel.bCmd,sLabel.bSubCmd,szStat,
- sLabel.CmdName,szMsg);
- else
- printf("\n%d\t%s\t%s %s",sLabel.bSubCmd,szStat,sLabel.CmdName,szMsg);
- }
-
- /*
- ** ErrMsg(ReqName,char *)
- ** - Pretty Print Standard Error Message with error tally increment
- */
- void ErrMsg(sLabel,szSt)
- ReqName sLabel;
- char *szSt;
- {
- extern WORD cwErrors;
- cwErrors++;
- Msg(sLabel,"-ERROR-",szSt);
- }
-
- /*
- ** WarningMsg(BYTE,BYTE,char *)
- ** - Pretty Print Standard Warning Message with warning tally increment
- **
- */
- void WarningMsg(sLabel,szSt)
- ReqName sLabel;
- char *szSt;
- {
- extern WORD cwWarnings;
- cwWarnings++;
- Msg(sLabel,"WARNING",szSt);
- }
-
- /*
- ** ReportMsg(BYTE,BYTE,char *)
- ** - Pretty Print Standard Report Message
- */
- void ReportMsg(sLabel,szSt)
- ReqName sLabel;
- char *szSt;
- {
- Msg(sLabel,"",szSt);
- }
-
- /*
- ** ErrorTest(WORD, BYTE, BYTE, char *)
- ** - Check status word and look up error code if the Error Bit is set
- */
- WORD ErrorTest(wStatus,sLabel)
- WORD wStatus;
- ReqName sLabel;
- {
- extern WORD cwErrors;
- // Device Driver Error Codes
-
- static char *szErrorCodes[] = {
- " Write-protect violation",
- " Unknown unit",
- " Drive not ready",
- " Unknown command",
- " CRC error",
- " Bad drive request structure length",
- " Seek error",
- " Unknown media",
- " Sector not found",
- " Printer out of paper",
- " Write fault",
- " Read fault",
- " General failure",
- " --reserved error code--",
- " --reserved error code--",
- " Invalid disk change"
- };
-
- if (wStatus & ERRORBIT)
- {
- cwErrors++;
- Msg(sLabel,"*ERROR*",szErrorCodes[ERRORMASK&wStatus]);
- }
- return (wStatus);
- }
-
-
- /*
- ** PrintAudInfo(AudInfo_Rec)
- ** - Pretty Print AudInfo_Rec's
- */
-
- void PrintAudInfo(ainf)
- AudInfo_Rec ainf;
- {
- printf("\nAudioInfo: Channel Status\n");
- printf("Channel %d mapped to channel 0 vol %d\n",ainf.in0,ainf.vol0);
- printf("Channel %d mapped to channel 1 vol %d\n",ainf.in1,ainf.vol1);
- printf("Channel %d mapped to channel 2 vol %d\n",ainf.in2,ainf.vol2);
- printf("Channel %d mapped to channel 3 vol %d\n",ainf.in3,ainf.vol3);
- }
-
- /* hexDump(BYTE *, WORD)
- **
- ** Quick Hex dump in 16 columns.
- **
- */
-
- void HexDump(pchBuf,nbytes)
- BYTE far *pchBuf;
- WORD nbytes;
- {
- WORD iIn,iOut,cNum,cChar;
- extern FILE *pOutFile;
- printf("\n\n%d bytes\n",nbytes);
- for (iIn=0;iIn<79;iIn++) fputc('-',pOutFile);
- fputc('\n',pOutFile);
- for (iOut=0,cNum=0,cChar=0;cNum < nbytes;iOut++) {
-
- fprintf(pOutFile,"%.4X\t",cChar);
-
- for (iIn=0; iIn<16;iIn++,cNum++)
- if (cNum<nbytes)
- fprintf(pOutFile,"%0.2X ",(BYTE)pchBuf[iIn+iOut*16]);
- else fprintf(pOutFile," ");
-
- fprintf(pOutFile," ");
-
- for (iIn=0; iIn<16;iIn++,cChar++) {
- if (isgraph(pchBuf[iIn+iOut*16])&&cChar<nbytes)
- fputc(pchBuf[iIn+iOut*16],pOutFile);
- else fputc(' ',pOutFile);
- };
- fputc('\n',pOutFile);
- };
- for (iIn=0;iIn<79;iIn++) fputc('-',pOutFile);
- fputc('\n',pOutFile);
- }
-
- /*
- ** (char far*) my_malloc (long)
- **
- ** Allocate the far memory for the transfer buffer.
- ** - from speed.c
- */
-
- BYTE _far *my_malloc( how_much )
- DWORD how_much;
- {
- BYTE _far *buffer=0;
-
- inregs.x.ax = 0x4800;
- inregs.x.bx = (short)(how_much >> 4) + 1;
- int86x(0x21, &inregs, &outregs, &segregs);
-
- if ( outregs.x.cflag == 0 )
- {
- buffer = (BYTE _far *)MAKELONG( 0, outregs.x.ax );
- _fmemset(buffer,0,(size_t)how_much);
- }
- else
- {
- printf("\nSize of largest available block is %d \n",outregs.x.bx);
- fatalError("MALLOC FAILURE");
- }
- return( buffer );
- }
-
-
- /* Free the far memory for the xfer buffer.
- */
- void my_free( buffer )
- BYTE _far *buffer;
- {
- inregs.x.ax = 0x4900;
- segregs.es = HIWORD( (DWORD)buffer );
- int86x(0x21, &inregs, &outregs, &segregs);
- }
-
- /*
- ** PrintRed(DWORD) - Pretty print a redbook addr
- */
- void PrintRed(lSector)
- DWORD lSector;
-
- {
- printf("%u:%u:%u",HIWORD(lSector)&0xff,
- LOWORD(lSector)>>8,LOWORD(lSector)&0xff);
- }
-
- /*
- ** RedDiff(DWORD,DWORD)
- ** - given two redbook addresses, returns their difference
- ** in Redbook time
- */
- DWORD RedDiff(lSectorA,lSectorB)
- DWORD lSectorA,lSectorB;
- {
- if (lSectorA > lSectorB)
- return hsg2red((red2hsg(lSectorA) - red2hsg(lSectorB)));
- else
- return hsg2red((red2hsg(lSectorB) - red2hsg(lSectorA)));
- }
-
- /* bcd2bin() -
- **
- ** DESCRIPTION
- ** Converts BCD to binary. BCD breaks a byte into two 4-bit
- ** nibbles where each ranges from 0-9. BCD can represent 0-99
- ** whereas binary does 0-255. If the value passed in is an
- ** illegal BCD value, we return 0xff
- */
- BYTE bcd2bin(c)
- BYTE c;
- {
- if ((c & 0x0f) > 0x09)
- return(0xff);
- if ((c & 0xf0) > 0x90)
- return(0xff);
- return ((BYTE)(((c&(BYTE)0xf0)>>4) * 10) + (BYTE)(c&(BYTE)0x0f));
- }
-
- /* red2hsg() -
- **
- ** DESCRIPTION
- ** Converts a binary red book address to high sierra addressing
- ** The msb of the red book is always zero, the next less significant
- ** byte is the minute (0-59+), then second (0-59) and lsb is the
- ** frame (0-75). The conversion is
- ** hsg = min * 60 * 75 + sec * 75 + frame;
- */
- DWORD red2hsg(l)
- DWORD l;
- {
- return((DWORD) (HIWORD(l) & 0xff) * 60 * 75 +
- (DWORD) (LOWORD(l) >> 8) * 75 +
- (DWORD) (LOWORD(l) & 0xff));
- }
- /* hsg2red(DWORD)
- **
- ** Does the opposite of red2hsg()
- **
- **
- */
- DWORD hsg2red(l)
- DWORD l;
- {
- DWORD min,sec,fra;
- min = l/(60*75);
- sec = (l%(60*75))/75;
- fra = (l%(60*75))%75;
- return (0x00ffffff&((min<<16)|(sec<<8)|fra));
- }
-
- /* find_drivers() -
- **
- ** Using INT 2Fh with AH=15h (the MSCDEX function request interface)
- ** we can ask MSCDEX for the number and location of all CDROM
- ** device drivers on the system.
- */
-
- void find_drivers(Dev_Tbl)
- Dev_List *Dev_Tbl;
- {
-
- extern WORD cwNumDrives,iFirstDrvLetter;
-
- union REGS inregs;
- union REGS outregs;
- struct SREGS segregs;
-
- BYTE far *d = (BYTE far *) Dev_Tbl;
- Dev_Hdr far *sdev;
- uint i;
-
- inregs.x.ax = 0x1500; // Get Number of CDROM drive letters
- inregs.x.bx = 0; // Init to zero
- int86(0x2f, &inregs, &outregs);
-
- // If number of drives returned is still 0, then MSCDEX
- // is not installed.
-
- if (outregs.x.bx == 0)
- fatalError("\tMSCDEX not installed, Exiting.");
-
- cwNumDrives = outregs.x.bx;
- iFirstDrvLetter = outregs.x.cx;
-
- printf("\tDEVICE DRIVER INFORMATION:: \n");
- printf("\t%d drive(s) found starting at %c:\n", cwNumDrives,
- iFirstDrvLetter + 'A');
-
- inregs.x.ax = 0x1501; // Get CDROM drive letter device list
- inregs.x.bx = LOWORD(d);
- segregs.es = HIWORD(d);
- int86x(0x2f, &inregs, &outregs, &segregs);
-
- if (outregs.x.cflag)
- fatalError("MSCDEX not present, Exiting.");
-
- for (i = 0; i < cwNumDrives; i++) {
- printf("\tDrive %c:%d unit %d / Device Header Address :: 0x%lx \n", i + iFirstDrvLetter + 'A',
- i,Dev_Tbl[i].sub_unit,Dev_Tbl[i].dev_addr);
- sdev = Dev_Tbl[i].dev_addr;
- printf("\tDrive Name (obtained via Device Header) :: '%8Fs'\n", sdev->sdevname);
- printf("\tDevice Attributes :: %x \n",(Dev_Tbl[i].dev_addr)->sdevatt);
- }
- }
-